﻿using System;
using System.Reflection;
using System.Xml;

namespace XNA.BLEND.parser {
  public enum ActionVal {
      INITIAL,
      [ActionVal( 1, 0, ActionProp.LOC )] LOC_X,
      [ActionVal( 2, 1, ActionProp.LOC )] LOC_Y,
      [ActionVal( 3, 2, ActionProp.LOC )] LOC_Z,
      [ActionVal( 13, 0, ActionProp.SCALE )] SCALE_X,
      [ActionVal( 14, 1, ActionProp.SCALE )] SCALE_Y,
      [ActionVal( 15, 2, ActionProp.SCALE )] SCALE_Z,
      [ActionVal( 16, 0, ActionProp.ROT_EUL )] ROT_EUL_X,
      [ActionVal( 17, 1, ActionProp.ROT_EUL )] ROT_EUL_Y,
      [ActionVal( 18, 2, ActionProp.ROT_EUL )] ROT_EUL_Z,
      [ActionVal( 25, 0, ActionProp.ROT_QUAT )] ROT_QUAT_W,
      [ActionVal( 26, 1, ActionProp.ROT_QUAT )] ROT_QUAT_X,
      [ActionVal( 27, 2, ActionProp.ROT_QUAT )] ROT_QUAT_Y,
      [ActionVal( 28, 3, ActionProp.ROT_QUAT )] ROT_QUAT_Z,
      [ActionVal( -1, 0, ActionProp.ROT_AXIS )] ROT_AXIS_A,
      [ActionVal( -1, 1, ActionProp.ROT_AXIS )] ROT_AXIS_X,
      [ActionVal( -1, 2, ActionProp.ROT_AXIS )] ROT_AXIS_Y,
      [ActionVal( -1, 3, ActionProp.ROT_AXIS )] ROT_AXIS_Z,
  }

  internal static class ActionValExtensions {
    internal static ActionVal from( BlendParser parser, dynamic elmFCurve ) {
      ActionVal result = ActionVal.INITIAL;
      
      ActionProp prop = ActionPropExtensions.from( parser, elmFCurve );

      int arrayindex = elmFCurve.array_index;

      foreach ( ActionVal v in (Enum.GetValues( typeof( ActionVal ) ) ) ) {
        ActionValAttribute attr = v.GetAttr();
        if ( attr != null && arrayindex == attr.ArrayIndex && prop == attr.ActionProp ) {
          result = v;
          break;
        }
      }

      return result;
    }

    public static ActionValAttribute GetAttr( this ActionVal THIS ) {
      MemberInfo mi = typeof(ActionVal).GetField( Enum.GetName( typeof(ActionVal), THIS ) );

      ActionValAttribute result = null;

      if ( mi != null ) {
        result = (ActionValAttribute)Attribute.GetCustomAttribute( mi, typeof( ActionValAttribute ) );
      }

      return result;
    }
  }

  public class ActionValAttribute : Attribute {
    public ActionValAttribute( int code, int arrayindex, ActionProp acprop ) {
      this.Code = code;
      this.ArrayIndex = arrayindex;
      this.ActionProp = acprop;
    }
    public int Code { get; private set; }
    public int ArrayIndex { get; private set; }
    public ActionProp ActionProp { get; private set; }
  }
}
